package gmongo

import (
	log "gitee.com/abril-cx/gtools/glog"
	"go.mongodb.org/mongo-driver/bson"
	mon "go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type ConnHandle struct {
	model  string
	fields []string
}

// 搜索用于过滤查询返回字段 写入用于过滤写入字段
func (c *ConnHandle) Select(fields ...string) *ConnHandle {
	c.fields = fields
	return c
}

// is_deleted  默认: false ( 即不查询已删除的数据 )
func (c *ConnHandle) Filter(query bson.M, is_deleted ...bool) *ConnFilter {
	if len(is_deleted) == 0 {
		query["deleted"] = nil // 默认不查询已删除的数据
	} else {
		if !is_deleted[0] {
			query["deleted"] = true
		}
	}
	return &ConnFilter{
		filter: query,
		model:  c.model,
		fields: c.fields,
	}
}

func (c *ConnHandle) CreateOne(data bson.M, opts ...*options.InsertOneOptions) (*mon.InsertOneResult, error) {
	fields, err := GetFields(c.model)
	if err != nil {
		return nil, log.ErrorReturn("获取字段失败", err.Error())
	}
	data = FiltrationData(fields, data)
	err = RequiredCheck(fields, data)
	if err != nil {
		return nil, log.ErrorReturn("缺少必填字段", err.Error(), fields, data)
	}
	data, err = DefaultModel(fields, data)
	if err != nil {
		return nil, log.ErrorReturn("默认字段处理失败")
	}
	DefaultCreate(data)
	return MongoConn.Collection(c.model).InsertOne(Ctx, data, opts...)
}

func (c *ConnHandle) CreateMany(datas []bson.M, opts ...*options.InsertManyOptions) (*mon.InsertManyResult, error) {
	fields, err := GetFields(c.model)
	if err != nil {
		return nil, log.ErrorReturn("获取字段失败", err.Error())
	}
	for k, v := range datas {
		datas[k] = FiltrationData(fields, v)
		err = RequiredCheck(fields, v)
		if err != nil {
			return nil, log.ErrorReturn("缺少必填字段", err.Error(), fields, v)
		}
		datas[k], err = DefaultModel(fields, v)
		if err != nil {
			return nil, log.ErrorReturn("默认字段处理失败", err.Error())
		}
		DefaultCreate(datas[k])
	}
	var dataSlice []interface{}
	for _, data := range datas {
		dataSlice = append(dataSlice, data)
	}
	return MongoConn.Collection(c.model).InsertMany(Ctx, dataSlice, opts...)
}

func (c *ConnHandle) FilterAnd(query bson.M, is_deleted ...bool) *ConnFilter {
	MongoConn.Collection(c.model).FindOne(Ctx, bson.M{
		"$and": []bson.M{query},
		"deleted": nil,
		"$or": []bson.M{
		    {"deleted": true},
			{"deleted": false},
		},
		"$nor": []bson.M{
		    {"deleted": false},
			{"deleted": true},
		},
		"$not": bson.M{
			"deleted": true,
		},
		"$in": bson.M{
		    "deleted": true,
			// "deleted": false,
		},
	})
	if len(is_deleted) == 0 {
		query["deleted"] = nil // 默认不查询已删除的数据
	} else {
		if !is_deleted[0] {
			query["deleted"] = true
		}
	}
	return &ConnFilter{
		filter: query,
		model:  c.model,
		fields: c.fields,
	}
}

func (c *ConnHandle) FilterOr(query bson.M, is_deleted ...bool) *ConnFilter {
	if len(is_deleted) == 0 {
		query["deleted"] = nil // 默认不查询已删除的数据
	} else {
		if !is_deleted[0] {
			query["deleted"] = true
		}
	}
	return &ConnFilter{
		filter: query,
		model:  c.model,
		fields: c.fields,
	}
}

func (c *ConnHandle) FilterIsDeleted(query bson.M, is_deleted ...bool) *ConnFilter {
	if len(is_deleted) == 0 {
		query["deleted"] = nil // 默认不查询已删除的数据
	} else {
		if !is_deleted[0] {
			query["deleted"] = true
		}
	}
	return &ConnFilter{
		filter: query,
		model:  c.model,
		fields: c.fields,
	}
}
